#include <iostream>
#include <unistd.h>
#include <vector>
#include <cstdio>
#include<string>
#include<functional>
#include "Pthread.hpp"
#include <pthread.h>
#include"LockGuard.hpp"
// using namespace std;
// __thread size_t b = 100;
// void *threadpross(void *arg)
// {
//     while (true)
//     {
//         cout << "Im is a  " << (char *)arg << "tid=" << pthread_self() << " "
//              << " b=" << b << endl;
//         b--;
//         if (b == 95)
//         {
//             pthread_exit(nullptr);
//         }
//         sleep(1);
//     }
// }
//pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 int ticket = 30;
 class threaddata
 {
    public:
threaddata(const string &name,pthread_mutex_t *lock)
:_name(name),_plock(lock)
{

}
pthread_mutex_t *_plock;
string _name;
 };
void Getickett(threaddata *data)
{
    while (true)
    {
         //LockGuard lockguard(lock->_name,&lock->__mutex);
        //pthread_mutex_lock(&mutex);
        //LockGuard locck("dasdas",&mutex);
        LockGuard locck(data->_name,data->_plock);
        if (ticket > 0)
        {
            usleep(1000);
            cout<<"线程"<<data->_name;
            printf("get a ticket: %d\n", ticket);
            ticket--;
           // pthread_mutex_unlock(&mutex);
        }
        else
        {
             //pthread_mutex_unlock(&mutex);
            break;
        }
    }
}
string getname()
{
    static int number=1;
    char name[64];
    snprintf(name,sizeof(name),"thread-%d",number++);
    return name;

}
int main()
{
        //pthread_t tid;
        //pthread_create(&tid,nullptr,threadpross,(void *)"thread 1");
    //         while(true)
    //     {
    //         b--;
    //        cout<<"Im is a main thread "<<endl;
    //        if(b==90)
    //     {
    // break;
    // }
    //        sleep(1);
    //     }
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);

    string name1 = getname();
    threaddata *lock1=new threaddata(name1,&mutex);
    Phreadpack<threaddata *> t1(name1, Getickett,lock1);
    //Phreadpack<string> t1(name1, Getickett,name1);

    string name2 = getname();
    threaddata *lock2=new threaddata(name2,&mutex);
     Phreadpack<threaddata *> t2(name2, Getickett,lock2);
     //Phreadpack<string> t2(name1, Getickett,name2);

    string name3 = getname();
    threaddata *lock3=new threaddata(name3,&mutex);
    Phreadpack<threaddata *> t3(name3, Getickett,lock3);
    //Phreadpack<string> t3(name1, Getickett,name3);
    
    string name4 = getname();
    threaddata *lock4=new threaddata(name4,&mutex);
    Phreadpack<threaddata *> t4(name4, Getickett,lock4);
    //Phreadpack<string> t4(name1, Getickett,name4);
     t1.start();
     t2.start();
     t3.start();
     t4.start();
     t1.join();
    t2.join();
    t3.join();
    t4.join();
    pthread_mutex_destroy(&mutex);
    return 0;
}


